#ifndef __DATAPACKAGE_H__
#define __DATAPACKAGE_H__

//set<T>
template<class T>
void operator <<= (O_STREAM& os, const set<T>& t)
{
	long lSize = t.size();
	os <<= lSize;
	set<T>::const_iterator itEnd = t.end();
	for(set<T>::const_iterator it = t.begin(); it != itEnd; it++)
		os <<= *it;
}
template<class T>
void operator >>= (I_STREAM& is, set<T>& t)
{
	t.clear();
	long lSize = 0;
	is >>= lSize;
	for(long l = 0; l < lSize; l++)
	{
		T m;
		is >>= m;
		t.insert(m);
	}
}

//vector<T>
template<class T>
void operator <<= (O_STREAM& os, const vector<T>& t)
{
	long lSize = t.size();
	os <<= lSize;
	for(long l = 0; l < lSize; l++)
		os <<= t[l];
}
template<class T>
void operator >>= (I_STREAM& is, vector<T>& t)
{
	long lSize = 0;
	is >>= lSize;
	t.resize(lSize);
	for(long l = 0; l < lSize; l++)
		is >>= t[l];
}


//map<K, V>
template<class K, class V>
void operator <<= (O_STREAM& os, const map<K, V>& t)
{
	long lSize = t.size();
	os <<= lSize;
	map<K, V>::const_iterator itEnd = t.end();
	for(map<K, V>::const_iterator it = t.begin(); it != itEnd; it++)
	{
		os <<= it->first;
		os <<= it->second;
	}
}
template<class K, class V>
void operator >>= (I_STREAM& is, map<K, V>& t)
{
	t.clear();
	long lSize(0);
	is >>= lSize;
	for(long l = 0; l < lSize; l++)
	{
		K k;
		V v;
		is >>= k;
		is >>= v;
		t.insert(make_pair(k, v));
	}
}


void operator <<= (O_STREAM& os, bool t);
void operator >>= (I_STREAM& is, bool& t);

void operator <<= (O_STREAM& os, char t);
void operator >>= (I_STREAM& is, char& t);
void operator <<= (O_STREAM& os, unsigned char t);
void operator >>= (I_STREAM& is, unsigned char& t);

void operator <<= (O_STREAM& os, short t);
void operator >>= (I_STREAM& is, short& t);
void operator <<= (O_STREAM& os, unsigned short t);
void operator >>= (I_STREAM& is, unsigned short& t);

void operator <<= (O_STREAM& os, long t);
void operator >>= (I_STREAM& is, long& t);
void operator <<= (O_STREAM& os, unsigned long t);
void operator >>= (I_STREAM& is, unsigned long& t);

void operator <<= (O_STREAM& os, float t);
void operator >>= (I_STREAM& is, float& t);

void operator <<= (O_STREAM& os, double t);
void operator >>= (I_STREAM& is, double& t);

void operator <<= (O_STREAM& os, const string& t);
void operator >>= (I_STREAM& is, string& t);

void write_byte_array(O_STREAM& os, const char* data, int length);
void read_byte_array(I_STREAM& is, char* data, int length);

void operator <<= (O_STREAM& os, const vector<char>& t);
void operator >>= (I_STREAM& is, vector<char>& t);

#endif //__DATAPACKAGE_H__